﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using thinger.VisionModels;

namespace thinger.VisitionDAL
{
   
    public class Zmotion
    {
        //返回句柄
        private IntPtr Handle;

        //初始化完成标志
        public bool connectedOK = false;

        /// <summary>
        /// 搜索IP地址集合
        /// </summary>
        /// <returns></returns>
        /// <summary>
        /// 搜索IP地址集合
        /// </summary>
        /// <returns></returns>
        public List<string> GetEhList()
        {
            StringBuilder ipAddressList = new StringBuilder(100);

            uint addbufferlength = 1000;

            int error = zmcaux.ZAux_SearchEthlist(ipAddressList, addbufferlength, 100);

            if (error == 0)
            {
                string result = ipAddressList.ToString().Trim();

                if (result.Contains(' '))
                {

                    return result.Split(' ').ToList();
                }
                else
                {
                    return new List<string>();
                }

            }
            return new List<string>();
        }
        public OperateResult OpenCard(string ipAddress)
        {
            int error = zmcaux.ZAux_OpenEth(ipAddress, out Handle);
            if (error == 0)
            {
                connectedOK = true;

                return new OperateResult()
                {
                    IsSuccess = true,
                    Message = "板卡连接成功"
                };
            }
            else
            {
                return new OperateResult()
                {
                    IsSuccess = false,
                    Message = "板卡连接失败，错误码：" + error
                };
            }
        }


        /// <summary>
        /// 初始化卡
        /// </summary>
        /// <param name="file">BAS文件</param>
        /// <param name="isROM">节点数</param>
        /// <returns>操作结果</returns>
        public OperateResult BasDown(string file, bool isROM = true)
        {
            if (connectedOK)
            {
                int error = zmcaux.ZAux_BasDown(Handle, file, isROM ? (uint)1 : 0);

                if (error == 0)
                {
                    return new OperateResult()
                    {
                        IsSuccess = true,
                        Message = "初始化执行成功"
                    };
                }
                else
                {
                    return new OperateResult()
                    {
                        IsSuccess = true,
                        Message = "文件下载失败"
                    };
                }
            }
            else
            {
                return new OperateResult()
                {
                    IsSuccess = true,
                    Message = "请检查是否连接正常"
                };
            }
        }

        public OperateResult CloseCard()
        {
            if (zmcaux.ZAux_Close(Handle) == 0)
            {
                Handle = IntPtr.Zero;
                connectedOK = false;
                return OperateResult.CreateSuccessResult();
            }
            return OperateResult.CreateFailResult();
        }

        /// <summary>
        /// 错误处理
        /// </summary>
        /// <param name="command">执行命令</param>
        /// <param name="error">错误码</param>
        private void ErrorHandler(string command, int error)
        {
            string result = string.Empty;
            switch (error)
            {
                case 0: break;
                default:
                    result = string.Format("{0}" + "指令执行错误，错误码为{1}", command, error);
                    break;
            }
            if (result.Length > 0)
            {
                throw new Exception(result);
            }
        }


        /// <summary>
        /// 通用运动验证
        /// </summary>
        /// <param name="axis">轴号</param>
        /// <returns>操作结果</returns>
        private OperateResult CommonMotionValidate(int axis)
        {
            OperateResult result = CommonInitedValidate();
            //判断是否已经初始化
            if (!result.IsSuccess) return result;

            //判断是否正在运行
            if (IsMoving(axis))
            {
                result.IsSuccess = false;
                result.Message = "轴正在运行";
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }

        /// <summary>
        /// 判断某个轴是否正在运行
        /// </summary>
        /// <param name="axis"></param>
        /// <returns></returns>
        public bool IsMoving(int axis)
        {
            OperateResult result = CommonInitedValidate();
            //判断是否已经初始化
            if (!result.IsSuccess) return false;
            //定义运行状态
            int runstate = -1;
            //定义错误码
            int error = 0;

            //获取轴状态
            error = zmcaux.ZAux_Direct_GetIfIdle(Handle, axis, ref runstate);
            //错误码验证
            ErrorHandler("ZAux_Direct_GetIfIdle", error);
            return runstate == 0;

        }

        /// <summary>
        /// 通用初始化验证
        /// </summary>
        /// <returns></returns>
        private OperateResult CommonInitedValidate()
        {
            OperateResult result = new OperateResult();
            //判断是否已经初始化
            if (!connectedOK)
            {
                result.IsSuccess = false;
                result.Message = "控制器未连接";
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }

        public int GetInitStatus()
        {
            float Bus_InitStatus = 0.0f;
            int error = zmcaux.ZAux_Direct_GetUserVar(Handle, "Bus_InitStatus", ref Bus_InitStatus);
            if (error == 0)
            {
                return Convert.ToInt32(Bus_InitStatus);
            }
            else
            {
                return -1;
            }
        }


        public int GetTotalAxisnum()
        {
            float Bus_InitStatus = -1.0f;
            int error = zmcaux.ZAux_Direct_GetUserVar(Handle, "Bus_TotalAxisnum", ref Bus_InitStatus);
            if (error == 0)
            {
                return Convert.ToInt32(Bus_InitStatus);
            }
            else
            {
                return -1;
            }
        }



        /// <summary>
        /// 连续运动
        /// </summary>
        /// <param name="axis">轴号</param>
        /// <param name="vel">运行速度</param>
        /// <param name="dir">方向</param>
        /// <param name="velMin">最小速度</param>
        /// <param name="acc">加速度</param>
        /// <param name="dec">减速度</param>
        /// <param name="sramp">S曲线时间</param>
        /// <returns>操作结果</returns>
        public OperateResult VMove(short axis, float vel, bool dir, float velMin, float acc, float dec, float sramp)
        {
            // 判断是否满足运动条件
            var result = CommonMotionValidate(axis);

            if (!result.IsSuccess) return result;

            //创建错误码
            int error = 0;

            try
            {

                //设置最小速度
                error = zmcaux.ZAux_Direct_SetLspeed(Handle, axis, velMin);
                ErrorHandler("ZAux_Direct_SetLspeed", error);

                //设置运行速度
                error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis, vel);
                ErrorHandler("ZAux_Direct_SetSpeed", error);

                //设置加速度
                error = zmcaux.ZAux_Direct_SetAccel(Handle, axis, acc);
                ErrorHandler("ZAux_Direct_SetAccel", error);

                //设置减速度
                error = zmcaux.ZAux_Direct_SetDecel(Handle, axis, dec);
                ErrorHandler("ZAux_Direct_SetDecel", error);

                //设置S曲线
                error = zmcaux.ZAux_Direct_SetSramp(Handle, axis, sramp);
                ErrorHandler("ZAux_Direct_SetSramp", error);

                //设置方向并运动
                error = zmcaux.ZAux_Direct_Single_Vmove(Handle, axis, dir ? 1 : -1);
                ErrorHandler("ZAux_Direct_Single_Vmove", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }

        /// <summary>
        /// 相对运动
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="vel"></param>
        /// <param name="distance"></param>
        /// <param name="velMin"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="sramp"></param>
        /// <returns></returns>
        public OperateResult MoveRelative(short axis, float vel, float distance, float velMin, float acc, float dec, float sramp)
        {
            // 判断是否满足运动条件
            var result = CommonMotionValidate(axis);

            if (!result.IsSuccess) return result;

            //创建错误码
            int error = 0;

            try
            {

                //设置最小速度
                error = zmcaux.ZAux_Direct_SetLspeed(Handle, axis, velMin);
                ErrorHandler("ZAux_Direct_SetLspeed", error);

                //设置运行速度
                error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis, vel);
                ErrorHandler("ZAux_Direct_SetSpeed", error);

                //设置加速度
                error = zmcaux.ZAux_Direct_SetAccel(Handle, axis, acc);
                ErrorHandler("ZAux_Direct_SetAccel", error);

                //设置减速度
                error = zmcaux.ZAux_Direct_SetDecel(Handle, axis, dec);
                ErrorHandler("ZAux_Direct_SetDecel", error);

                //设置S曲线
                error = zmcaux.ZAux_Direct_SetSramp(Handle, axis, sramp);
                ErrorHandler("ZAux_Direct_SetSramp", error);

                //设置方向并运动
                error = zmcaux.ZAux_Direct_Single_Move(Handle, axis, distance);
                ErrorHandler("ZAux_Direct_Single_Move", error);

                result = WaitStop(axis);

                if (!result.IsSuccess) return result;
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }


        /// <summary>
        /// 绝对运动
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="vel"></param>
        /// <param name="pos"></param>
        /// <param name="velMin"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="sramp"></param>
        /// <returns></returns>
        public OperateResult MoveAbs(short axis, float vel, float pos, float velMin, float acc, float dec, float sramp)
        {
            // 判断是否满足运动条件
            var result = CommonMotionValidate(axis);

            if (!result.IsSuccess) return result;

            //创建错误码
            int error = 0;

            try
            {
                //设置最小速度
                error = zmcaux.ZAux_Direct_SetLspeed(Handle, axis, velMin);
                ErrorHandler("ZAux_Direct_SetLspeed", error);

                //设置运行速度
                error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis, vel);
                ErrorHandler("ZAux_Direct_SetSpeed", error);

                //设置加速度
                error = zmcaux.ZAux_Direct_SetAccel(Handle, axis, acc);
                ErrorHandler("ZAux_Direct_SetAccel", error);

                //设置减速度
                error = zmcaux.ZAux_Direct_SetDecel(Handle, axis, dec);
                ErrorHandler("ZAux_Direct_SetDecel", error);

                //设置S曲线
                error = zmcaux.ZAux_Direct_SetSramp(Handle, axis, sramp);
                ErrorHandler("ZAux_Direct_SetSramp", error);

                //设置方向并运动
                error = zmcaux.ZAux_Direct_Single_MoveAbs(Handle, axis, pos);
                ErrorHandler("ZAux_Direct_Single_MoveAbs", error);

                result = WaitStop(axis);

                if (!result.IsSuccess) return result;

            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }


        /// <summary>
        /// 2轴相对定位
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="vel"></param>
        /// <param name="distance"></param>
        /// <param name="velMin"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="sramp"></param>
        /// <returns></returns>
        public OperateResult Move2DRelative(short[] axis, float[] vel, float[] distance, float[] velMin, float[] acc, float[] dec, float[] sramp)
        {
            if (axis.Length == 2 && vel.Length == 2 && distance.Length == 2 && velMin.Length == 2 && acc.Length == 2 && dec.Length == 2 && sramp.Length == 2)
            {
                OperateResult result = new OperateResult();

                //相对定位
                for (int i = 0; i < 2; i++)
                {
                    result = MoveRelative(axis[i], vel[i], distance[i], velMin[i], acc[i], dec[i], sramp[i]);

                    if (!result.IsSuccess) return result;
                }

                //等待停止
                for (int i = 0; i < 2; i++)
                {
                    result = WaitStop(axis[i]);

                    if (!result.IsSuccess) return result;
                }

                return OperateResult.CreateSuccessResult();

            }

            return new OperateResult()
            {
                IsSuccess = false,
                Message = "传递参数长度不正确"
            };

        }

        /// <summary>
        /// 2轴绝对定位
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="vel"></param>
        /// <param name="distance"></param>
        /// <param name="velMin"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="sramp"></param>
        /// <returns></returns>
        public OperateResult Move2DAbs(short[] axis, float[] vel, float[] pos, float[] velMin, float[] acc, float[] dec, float[] sramp)
        {
            if (axis.Length == 2 && vel.Length == 2 && pos.Length == 2 && velMin.Length == 2 && acc.Length == 2 && dec.Length == 2 && sramp.Length == 2)
            {
                OperateResult result = new OperateResult();

                //相对定位
                for (int i = 0; i < 2; i++)
                {
                    result = MoveAbs(axis[i], vel[i], pos[i], velMin[i], acc[i], dec[i], sramp[i]);

                    if (!result.IsSuccess) return result;
                }

                //等待停止
                for (int i = 0; i < 2; i++)
                {
                    result = WaitStop(axis[i]);

                    if (!result.IsSuccess) return result;
                }

                return OperateResult.CreateSuccessResult();

            }

            return new OperateResult()
            {
                IsSuccess = false,
                Message = "传递参数长度不正确"
            };

        }


        /// <summary>
        /// 3轴相对定位
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="vel"></param>
        /// <param name="distance"></param>
        /// <param name="velMin"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="sramp"></param>
        /// <returns></returns>
        public OperateResult Move3DRelative(short[] axis, float[] vel, float[] distance, float[] velMin, float[] acc, float[] dec, float[] sramp)
        {
            if (axis.Length == 3 && vel.Length == 3 && distance.Length == 3 && velMin.Length == 3 && acc.Length == 3 && dec.Length == 3 && sramp.Length == 3)
            {
                OperateResult result = new OperateResult();

                //2轴定位
                result = Move2DRelative(new short[] { axis[0], axis[1] }, new float[] { vel[0], vel[1] }, new float[] { distance[0], distance[1] },

                    new float[] { velMin[0], velMin[1] }, new float[] { acc[0], acc[1] }, new float[] { dec[0], dec[1] }, new float[] { sramp[0], sramp[1] });
                if (!result.IsSuccess) return result;


                result = MoveRelative(axis[2], vel[2], distance[2], velMin[2], acc[2], dec[2], sramp[2]);
                if (!result.IsSuccess) return result;

                //等待停止
                result = WaitStop(axis[2]);
                if (!result.IsSuccess) return result;

                return OperateResult.CreateSuccessResult();
            }

            return new OperateResult()
            {
                IsSuccess = false,
                Message = "传递参数长度不正确"
            };

        }


        /// <summary>
        /// 3轴绝对定位
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="vel"></param>
        /// <param name="distance"></param>
        /// <param name="velMin"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="sramp"></param>
        /// <returns></returns>
        public OperateResult Move3DAbs(short[] axis, float[] vel, float[] distance, float[] velMin, float[] acc, float[] dec, float[] sramp)
        {
            if (axis.Length == 3 && vel.Length == 3 && distance.Length == 3 && velMin.Length == 3 && acc.Length == 3 && dec.Length == 3 && sramp.Length == 3)
            {
                OperateResult result = new OperateResult();

                //先动Z轴
                result = MoveAbs(axis[2], vel[2], 0.0f, velMin[2], acc[2], dec[2], sramp[2]);
                if (!result.IsSuccess) return result;

                //等待停止
                result = WaitStop(axis[2]);
                if (!result.IsSuccess) return result;

                //2轴定位
                result = Move2DAbs(new short[] { axis[0], axis[1] }, new float[] { vel[0], vel[1] }, new float[] { distance[0], distance[1] },

                    new float[] { velMin[0], velMin[1] }, new float[] { acc[0], acc[1] }, new float[] { dec[0], dec[1] }, new float[] { sramp[0], sramp[1] });
                if (!result.IsSuccess) return result;


                result = MoveAbs(axis[2], vel[2], distance[2], velMin[2], acc[2], dec[2], sramp[2]);
                if (!result.IsSuccess) return result;

                //等待停止
                result = WaitStop(axis[2]);
                if (!result.IsSuccess) return result;

                return OperateResult.CreateSuccessResult();
            }

            return new OperateResult()
            {
                IsSuccess = false,
                Message = "传递参数长度不正确"
            };

        }


        /// <summary>
        /// 多轴相对直线插补
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="distance"></param>
        /// <param name="vel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <returns></returns>
        public OperateResult MoveLineRelative(int[] axis, float[] distance, float vel, float acc, float dec)
        {

            if (axis.Length >= 2 && axis.Length == distance.Length)
            {
                OperateResult result = new OperateResult();

                //判断每个轴是否满足要求
                foreach (var item in axis)
                {
                    result = CommonMotionValidate((short)item);
                    if (!result.IsSuccess) return result;
                }

                int error = 0;
                try
                {
                    //选择 BASE 轴列表
                    error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
                    ErrorHandler("ZAux_Direct_Base", error);

                    error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
                    ErrorHandler("ZAux_Direct_SetSpeed", error);

                    error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
                    ErrorHandler("ZAux_Direct_SetAccel", error);

                    error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
                    ErrorHandler("ZAux_Direct_SetDecel", error);

                    error = zmcaux.ZAux_Direct_Move(Handle, axis.Length, axis, distance);
                    ErrorHandler("ZAux_Direct_Move", error);

                    //等待停止
                    for (int i = 0; i < 2; i++)
                    {
                        result = WaitStop((short)axis[i]);

                        if (!result.IsSuccess) return result;
                    }

                    return OperateResult.CreateSuccessResult();
                }
                catch (Exception ex)
                {
                    result.IsSuccess = false;
                    result.Message = ex.Message;
                    return result;
                }

            }

            return new OperateResult()
            {
                IsSuccess = false,
                Message = "传递参数不正确"
            };
        }

        /// <summary>
        /// 多轴绝对直线插补
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="distance"></param>
        /// <param name="vel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <returns></returns>
        public OperateResult MoveLineAbs(int[] axis, float[] pos, float vel, float acc, float dec)
        {

            if (axis.Length >= 2 && axis.Length == pos.Length)
            {
                OperateResult result = new OperateResult();

                //判断每个轴是否满足要求
                foreach (var item in axis)
                {
                    result = CommonMotionValidate((short)item);
                    if (!result.IsSuccess) return result;
                }

                int error = 0;
                try
                {
                    //选择 BASE 轴列表
                    error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
                    ErrorHandler("ZAux_Direct_Base", error);

                    error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
                    ErrorHandler("ZAux_Direct_SetSpeed", error);

                    error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
                    ErrorHandler("ZAux_Direct_SetAccel", error);

                    error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
                    ErrorHandler("ZAux_Direct_SetDecel", error);

                    error = zmcaux.ZAux_Direct_MoveAbs(Handle, axis.Length, axis, pos);
                    ErrorHandler("ZAux_Direct_Move", error);

                    //等待停止
                    for (int i = 0; i < 2; i++)
                    {
                        result = WaitStop((short)axis[i]);

                        if (!result.IsSuccess) return result;
                    }

                    return OperateResult.CreateSuccessResult();
                }
                catch (Exception ex)
                {
                    result.IsSuccess = false;
                    result.Message = ex.Message;
                    return result;
                }
            }

            return new OperateResult()
            {
                IsSuccess = false,
                Message = "传递参数不正确"
            };
        }

        /// <summary>
        /// XY圆弧相对插补(圆心定位)
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="distance"></param>
        /// <param name="circlecenter"></param>
        /// <param name="vel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="dir"></param>
        /// <returns></returns>
        public OperateResult MoveCircleRelative(int[] axis, float[] distance, float[] circlecenter, float vel, float acc, float dec, int dir)
        {

            if (axis.Length == 2 && axis.Length == distance.Length)
            {
                OperateResult result = new OperateResult();

                //判断每个轴是否满足要求
                foreach (var item in axis)
                {
                    result = CommonMotionValidate((short)item);
                    if (!result.IsSuccess) return result;
                }

                int error = 0;
                try
                {
                    //选择 BASE 轴列表
                    error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
                    ErrorHandler("ZAux_Direct_Base", error);

                    error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
                    ErrorHandler("ZAux_Direct_SetSpeed", error);

                    error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
                    ErrorHandler("ZAux_Direct_SetAccel", error);

                    error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
                    ErrorHandler("ZAux_Direct_SetDecel", error);

                    error = zmcaux.ZAux_Direct_MoveCirc(Handle, axis.Length, axis, distance[0], distance[1], circlecenter[0], circlecenter[1], dir);
                    ErrorHandler("ZAux_Direct_MoveCirc", error);

                    return OperateResult.CreateSuccessResult();
                }
                catch (Exception ex)
                {
                    result.IsSuccess = false;
                    result.Message = ex.Message;
                    return result;
                }

            }

            return new OperateResult()
            {
                IsSuccess = false,
                Message = "传递参数不正确"
            };
        }


        /// <summary>
        /// XY圆弧绝对插补(圆心定位)
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="distance"></param>
        /// <param name="circlecenter"></param>
        /// <param name="vel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="dir"></param>
        /// <returns></returns>
        public OperateResult MoveCircleAbs(int[] axis, float[] distance, float[] circlecenter, float vel, float acc, float dec, int dir)
        {

            if (axis.Length == 2 && axis.Length == distance.Length)
            {
                OperateResult result = new OperateResult();

                //判断每个轴是否满足要求
                foreach (var item in axis)
                {
                    result = CommonMotionValidate((short)item);
                    if (!result.IsSuccess) return result;
                }

                int error = 0;
                try
                {
                    //选择 BASE 轴列表
                    error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
                    ErrorHandler("ZAux_Direct_Base", error);

                    error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
                    ErrorHandler("ZAux_Direct_SetSpeed", error);

                    error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
                    ErrorHandler("ZAux_Direct_SetAccel", error);

                    error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
                    ErrorHandler("ZAux_Direct_SetDecel", error);

                    error = zmcaux.ZAux_Direct_MoveCircAbs(Handle, axis.Length, axis, distance[0], distance[1], circlecenter[0], circlecenter[1], dir);
                    ErrorHandler("ZAux_Direct_MoveCircAbs", error);

                    return OperateResult.CreateSuccessResult();
                }
                catch (Exception ex)
                {
                    result.IsSuccess = false;
                    result.Message = ex.Message;
                    return result;
                }

            }

            return new OperateResult()
            {
                IsSuccess = false,
                Message = "传递参数不正确"
            };
        }


        /// <summary>
        /// XY圆弧相对插补(中点定位)
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="distance"></param>
        /// <param name="midpos"></param>
        /// <param name="vel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <returns></returns>
        public OperateResult MoveCircle2Relative(int[] axis, float[] distance, float[] midpos, float vel, float acc, float dec)
        {

            if (axis.Length == 2 && axis.Length == distance.Length)
            {
                OperateResult result = new OperateResult();

                //判断每个轴是否满足要求
                foreach (var item in axis)
                {
                    result = CommonMotionValidate((short)item);
                    if (!result.IsSuccess) return result;
                }

                int error = 0;
                try
                {
                    //选择 BASE 轴列表
                    error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
                    ErrorHandler("ZAux_Direct_Base", error);

                    error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
                    ErrorHandler("ZAux_Direct_SetSpeed", error);

                    error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
                    ErrorHandler("ZAux_Direct_SetAccel", error);

                    error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
                    ErrorHandler("ZAux_Direct_SetDecel", error);

                    error = zmcaux.ZAux_Direct_MoveCirc2(Handle, axis.Length, axis, midpos[0], midpos[1], distance[0], distance[1]);
                    ErrorHandler("ZAux_Direct_MoveCirc", error);

                    return OperateResult.CreateSuccessResult();
                }
                catch (Exception ex)
                {
                    result.IsSuccess = false;
                    result.Message = ex.Message;
                    return result;
                }

            }

            return new OperateResult()
            {
                IsSuccess = false,
                Message = "传递参数不正确"
            };
        }


        /// <summary>
        /// XY圆弧绝对插补(中点定位)
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="distance"></param>
        /// <param name="midpos"></param>
        /// <param name="vel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <returns></returns>
        public OperateResult MoveCircle2Abs(int[] axis, float[] distance, float[] midpos, float vel, float acc, float dec)
        {

            if (axis.Length == 2 && axis.Length == distance.Length)
            {
                OperateResult result = new OperateResult();

                //判断每个轴是否满足要求
                foreach (var item in axis)
                {
                    result = CommonMotionValidate((short)item);
                    if (!result.IsSuccess) return result;
                }

                int error = 0;
                try
                {
                    //选择 BASE 轴列表
                    error = zmcaux.ZAux_Direct_Base(Handle, axis.Length, axis);
                    ErrorHandler("ZAux_Direct_Base", error);

                    error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis[0], vel);
                    ErrorHandler("ZAux_Direct_SetSpeed", error);

                    error = zmcaux.ZAux_Direct_SetAccel(Handle, axis[0], acc);
                    ErrorHandler("ZAux_Direct_SetAccel", error);

                    error = zmcaux.ZAux_Direct_SetDecel(Handle, axis[0], dec);
                    ErrorHandler("ZAux_Direct_SetDecel", error);

                    error = zmcaux.ZAux_Direct_MoveCirc2Abs(Handle, axis.Length, axis, midpos[0], midpos[1], distance[0], distance[1]);
                    ErrorHandler("ZAux_Direct_MoveCirc2Abs", error);

                    return OperateResult.CreateSuccessResult();
                }
                catch (Exception ex)
                {
                    result.IsSuccess = false;
                    result.Message = ex.Message;
                    return result;
                }

            }

            return new OperateResult()
            {
                IsSuccess = false,
                Message = "传递参数不正确"
            };
        }


        /// <summary>
        /// 通用回零操作
        /// </summary>
        /// <param name="axis">轴号</param>
        /// <param name="vel">速度</param>
        /// <param name="creep">爬行速度</param>
        /// <param name="homeio">HomeIO</param>
        /// <param name="distance">原限距离</param>
        /// <param name="velMin">最小速度</param>
        /// <param name="acc">加速度</param>
        /// <param name="dec">减速度</param>
        /// <param name="sramp">s曲线时间</param>
        /// <param name="homemode">回零模式</param>
        /// <returns>操作结果</returns>
        public OperateResult ZeroAxis(short axis, float vel, float creep, int homeio, float distance, float velMin, float acc, float dec, float sramp, int homemode = 4)
        {
            // 判断是否满足运动条件
            var result = CommonMotionValidate(axis);

            if (!result.IsSuccess) return result;

            //先往原点方向一直走，直到到达限位
            result = MoveRelative(axis, vel, -500, velMin, acc, dec, sramp);
            if (!result.IsSuccess) return result;

            //等待停止
            result = WaitStop(axis);
            if (!result.IsSuccess) return result;

            //位置
            result = ZeroPos(axis);
            if (!result.IsSuccess) return result;

            //往反向走一段距离，超过原点和限位的距离
            result = MoveRelative(axis, vel, distance, velMin, acc, dec, sramp);
            if (!result.IsSuccess) return result;

            //等待停止
            result = WaitStop(axis);
            if (!result.IsSuccess) return result;

            //直接回零
            result = DirectZeroAxis(axis, vel, creep, homeio, velMin, acc, dec, homemode);
            if (!result.IsSuccess) return result;

            //等待回零停止
            result = WaitHomeStop(axis);
            if (!result.IsSuccess) return result;

            //返回成功
            return OperateResult.CreateSuccessResult();

        }


        /// <summary>
        /// 直接回原点
        /// </summary>
        /// <param name="axis">轴号</param>
        /// <param name="vel">速度</param>
        /// <param name="creep">爬行速度</param>
        /// <param name="homeio">原点IO点</param>
        /// <param name="velMin">最小速度</param>
        /// <param name="acc">加速度</param>
        /// <param name="dec">减速度</param>
        /// <param name="homemode">回零模式</param>
        /// <returns>操作</returns>
        public OperateResult DirectZeroAxis(short axis, float vel, float creep, int homeio, float velMin, float acc, float dec, int homemode = 4)
        {
            // 判断是否满足运动条件
            var result = CommonMotionValidate(axis);

            if (!result.IsSuccess) return result;

            //创建错误码
            int error = 0;

            try
            {

                //设置最小速度
                error = zmcaux.ZAux_Direct_SetLspeed(Handle, axis, velMin);
                ErrorHandler("ZAux_Direct_SetLspeed", error);

                //设置运行速度
                error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis, vel);
                ErrorHandler("ZAux_Direct_SetSpeed", error);

                //设置加速度
                error = zmcaux.ZAux_Direct_SetAccel(Handle, axis, acc);
                ErrorHandler("ZAux_Direct_SetAccel", error);

                //设置减速度
                error = zmcaux.ZAux_Direct_SetDecel(Handle, axis, dec);
                ErrorHandler("ZAux_Direct_SetDecel", error);

                //设置爬行速度
                error = zmcaux.ZAux_Direct_SetCreep(Handle, axis, creep);
                ErrorHandler("ZAux_Direct_SetCreep", error);

                //设置HomeIO
                error = zmcaux.ZAux_Direct_SetDatumIn(Handle, axis, homeio);
                ErrorHandler("ZAux_Direct_SetDatumIn", error);

                //执行回原点
                error = zmcaux.ZAux_Direct_Single_Datum(Handle, axis, homemode);
                ErrorHandler("ZAux_Direct_Single_Datum", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }


        /// <summary>
        /// 总线回原点
        /// </summary>
        /// <param name="axis">轴号</param>
        /// <param name="vel">速度</param>
        /// <param name="creep">爬行速度</param>
        /// <param name="homeio">原点IO点</param>
        /// <param name="velMin">最小速度</param>
        /// <param name="acc">加速度</param>
        /// <param name="dec">减速度</param>
        /// <param name="homemode">回零模式</param>
        /// <returns>操作</returns>
        public OperateResult BUSZeroAxis(short axis, float vel, float creep, float offset, uint homemode)
        {
            // 判断是否满足运动条件
            var result = CommonMotionValidate(axis);

            if (!result.IsSuccess) return result;

            //创建错误码
            int error = 0;

            try
            {
                //设置运行速度
                error = zmcaux.ZAux_Direct_SetSpeed(Handle, axis, vel);
                ErrorHandler("ZAux_Direct_SetSpeed", error);

                //设置爬行速度
                error = zmcaux.ZAux_Direct_SetCreep(Handle, axis, creep);
                ErrorHandler("ZAux_Direct_SetCreep", error);

                //设置offset
                error = zmcaux.ZAux_BusCmd_SetDatumOffpos(Handle, (uint)axis, offset);
                ErrorHandler("ZAux_BusCmd_SetDatumOffpos", error);

                //执行回原点
                error = zmcaux.ZAux_BusCmd_Datum(Handle, (uint)axis, homemode);
                ErrorHandler("ZAux_BusCmd_Datum", error);

            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }


        /// <summary>
        /// 等待停止
        /// </summary>
        /// <param name="axis">轴号</param>
        /// <returns></returns>
        public OperateResult WaitStop(short axis)
        {
            // 判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return result;

            int error = 0;

            int runstate = 0;

            do
            {
                error = zmcaux.ZAux_Direct_GetIfIdle(Handle, axis, ref runstate);

                ErrorHandler("ZAux_Direct_GetIfIdle", error);

            } while (runstate == 0);

            return OperateResult.CreateSuccessResult();
        }


        /// <summary>
        /// 等待回零停止
        /// </summary>
        /// <param name="axis">轴号</param>
        /// <returns></returns>
        public OperateResult WaitHomeStop(short axis)
        {
            // 判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return result;


            int error = 0;

            uint homestate = 0;

            do
            {
                error = zmcaux.ZAux_Direct_GetHomeStatus(Handle, axis, ref homestate);

                ErrorHandler("ZAux_Direct_GetHomeStatus", error);

            } while (homestate == 0);

            return OperateResult.CreateSuccessResult();
        }

        /// <summary>
        /// 等待回零停止
        /// </summary>
        /// <param name="axis">轴号</param>
        /// <returns></returns>
        public OperateResult WaitBusHomeStop(short axis)
        {
            // 判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return result;


            int error = 0;

            int runstate = 0;

            do
            {
                error = zmcaux.ZAux_Direct_GetIfIdle(Handle, axis, ref runstate);

                ErrorHandler("ZAux_Direct_GetIfIdle", error);

            } while (runstate == 0);


            uint homeStatus = 0;
            zmcaux.ZAux_BusCmd_GetHomeStatus(Handle, (uint)axis, ref homeStatus);

            return homeStatus == 1 ? OperateResult.CreateSuccessResult() : OperateResult.CreateFailResult();
        }



        /// <summary>
        /// 停止轴
        /// </summary>
        /// <param name="axis">轴号</param>
        /// <returns>操作结果</returns>
        public OperateResult StopAxis(short axis)
        {
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return result;

            //错误码
            int error = 0;

            try
            {
                /*         
                0 （缺省）取消当前运动
                1 取消缓冲的运动
                2 取消当前运动和缓冲运动
                3 立即中断脉冲发送
                 */

                error = zmcaux.ZAux_Direct_Single_Cancel(Handle, axis, 2);
                ErrorHandler("ZAux_Direct_Single_Cancel", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }


        /// <summary>
        /// 停止所有轴
        /// </summary>
        /// <returns></returns>
        public OperateResult StopAllAxis()
        {
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return result;

            //错误码
            int error = 0;

            try
            {
                /*         
                    0取消当前运动 。
                    1取消缓冲的运动 。
                    2取消当前运动和缓冲运动 。
                    3 立即停止。
                 */
                error = zmcaux.ZAux_Direct_CancelAxisList(Handle, 6, new int[] { 0, 1, 2, 3, 4, 5 }, 3);
                ErrorHandler("ZAux_Direct_CancelAxisList", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
            return OperateResult.CreateSuccessResult();

        }

        /// <summary>
        /// 获取实时速度
        /// </summary>
        /// <param name="axis"></param>
        /// <returns></returns>
        public float GetVel(short axis)
        {
            //判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return 0.0f;

            //定义速度
            float vel = 0.0f;

            //定义错误码
            int error = 0;

            try
            {
                error = zmcaux.ZAux_Direct_GetVpSpeed(Handle, axis, ref vel);

                ErrorHandler("ZAux_Direct_GetVpSpeed", error);

                return vel;

            }
            catch (Exception)
            {
                return 0.0f;
            }
        }


        /// <summary>
        /// 获取实时位置
        /// </summary>
        /// <param name="axis"></param>
        /// <returns></returns>
        public float GetPos(short axis)
        {
            //判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return 0.0f;

            //定义位置
            float pos = 0.0f;

            //定义错误码
            int error = 0;

            try
            {
                error = zmcaux.ZAux_Direct_GetMpos(Handle, axis, ref pos);

                ErrorHandler("ZAux_Direct_GetMpos", error);

                return pos;

            }
            catch (Exception)
            {
                return 0.0f;
            }
        }


        /// <summary>
        /// 位置清零
        /// </summary>
        /// <param name="axis"></param>
        /// <returns></returns>
        public OperateResult ZeroPos(short axis)
        {
            //判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return result;

            //定义错误码
            int error = 0;

            try
            {
                error = zmcaux.ZAux_Direct_SetMpos(Handle, axis, 0.0f);

                ErrorHandler("ZAux_Direct_SetMpos", error);

            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }

        public OperateResult ClearError(int axis)
        {
            //判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return result;

            //定义错误码
            int error = 0;

            try
            {
                error = zmcaux.ZAux_BusCmd_DriveClear(Handle, (uint)axis, 0);

                ErrorHandler("ZAux_BusCmd_DriveClear", error);

            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }

        public OperateResult SetEnable(int axis, bool isEnable)
        {
            //判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return result;

            //定义错误码
            int error = 0;

            try
            {
                error = zmcaux.ZAux_Direct_SetAxisEnable(Handle, axis, isEnable ? 1 : 0);

                ErrorHandler("ZAux_Direct_SetAxisEnable", error);

            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }

        public OperateResult SetOutput(int ioNum, bool value)
        {
            //判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return result;

            //定义错误码
            int error = 0;

            try
            {
                error = zmcaux.ZAux_Direct_SetOp(Handle, ioNum, value ? (uint)1 : 0);

                ErrorHandler("ZAux_Direct_SetOp", error);

            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
            return OperateResult.CreateSuccessResult();
        }

        public bool GetEnable(int axis)
        {

            //判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return false;

            int enable = -1;

            //定义错误码
            int error = 0;

            try
            {
                error = zmcaux.ZAux_Direct_GetAxisEnable(Handle, axis, ref enable);

                ErrorHandler("ZAux_Direct_GetAxisEnable", error);

                return enable == 1;

            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool GetOutput(int ioNum)
        {

            //判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return false;

            uint data = 0;

            //定义错误码
            int error = 0;

            try
            {
                error = zmcaux.ZAux_Direct_GetOp(Handle, ioNum, ref data);

                ErrorHandler("ZAux_Direct_GetOp", error);

                return data == 1;

            }
            catch (Exception)
            {
                return false;
            }
        }


        public bool GetInput(int ioNum)
        {

            //判断是否满足初始化条件
            var result = CommonInitedValidate();

            if (!result.IsSuccess) return false;

            uint data = 0;

            //定义错误码
            int error = 0;

            try
            {
                error = zmcaux.ZAux_Direct_GetIn(Handle, ioNum, ref data);

                ErrorHandler("ZAux_Direct_GetIn", error);

                return data == 1;

            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}
